package cn.banacoo.common.dto;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import com.google.common.collect.Lists;

import net.sf.cglib.beans.BeanCopier;


/**
 * @author zengzp
 * @date 2017年5月23日 下午3:12:17
 * @describtion 基础对象Vo
 * @version 1.0
 */
public class BaseDto implements Serializable {
	private static final transient long serialVersionUID = 1L;
	private static ConcurrentMap<String, BeanCopier> beanCopiers = new ConcurrentHashMap<String, BeanCopier>();

	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.SHORT_PREFIX_STYLE).toString();
	}

	public String toLineString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.MULTI_LINE_STYLE).toString();
	}

	/**
	 * @describtion 对象属性拷贝 比反射机制快
	 * @author zengzp
	 * @date 2017年5月23日 下午5:49:08
	 * @version 1.0
	 */
	@SuppressWarnings("unchecked")
	public <T> T copyTo(Class<T> clz) {
		try {
			Object clone = clz.newInstance();
			String key = clz.getName() + ":" + getClass().getName();

			BeanCopier copier = null;
			if (beanCopiers.containsKey(key)) {
				copier = (BeanCopier) beanCopiers.get(key);
			} else {
				copier = BeanCopier.create(getClass(), clz, false);
				beanCopiers.putIfAbsent(key, copier);
			}
			copier.copy(this, clone, null);
			return (T) clone;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * @describtion 列表拷贝
	 * @author zengzp
	 * @date 2017年5月23日 下午5:49:21
	 * @version 1.0
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static <A extends BaseDto, B extends BaseDto> List<B> copyListTo(
			List<A> sources, Class<B> clz) {
		try {
			if (sources == null) {
				return null;
			}
			List newList = Lists.newArrayList();
			if (sources.size() == 0) {
				return newList;
			}
			BaseDto val = (BaseDto) sources.get(0);
			String key = clz.getName() + ":" + val.getClass().getName();

			BeanCopier copier = null;
			if (beanCopiers.containsKey(key)) {
				copier = (BeanCopier) beanCopiers.get(key);
			} else {
				copier = BeanCopier.create(val.getClass(), clz, false);
				beanCopiers.putIfAbsent(key, copier);
			}
			for (BaseDto a : sources) {
				BaseDto clone = (BaseDto) clz.newInstance();
				copier.copy(a, clone, null);
				newList.add(clone);
			}
			return newList;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * @describtion 对象转map
	 * @author zengzp
	 * @date 2017年5月23日 下午5:49:04
	 * @version 1.0
	 */
	public HashMap<String, Object> object2Map(){    
		HashMap<String, Object> map = new HashMap<String, Object>(); 
		try {
			Field[] declaredFields = this.getClass().getDeclaredFields();
			for (Field field : declaredFields) {    
				field.setAccessible(true);  
				map.put(field.getName(), field.get(this));
			}  
        } catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} 
        return map;  
    }   
}
